package com.tianqu.tms.core.base;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.util.MessageResources;

import com.tianqu.tms.core.exception.SessionTimeoutException;
import com.tianqu.tms.core.exception.TmsException;
import com.tianqu.tms.core.util.StringUtil;
import com.tianqu.tms.core.util.TmsConstants;

/**
 * Description:      ajax用的action父类
 * @author liugang
 *
 */
public abstract class TmsAjaxAction extends Action {
	
	public Logger logger = Logger.getLogger(TmsAjaxAction.class);

	public final static String XML = "xml";
	public final static String TEXT = "text";
	
	/** ***** Session内使用的key *********** */
	public static final String LAST_ACTION_MAPPING = "LAST.ACTION.MAPPING";
	public static final String APPLICATION_USER_CONTEXT_KEY = "applicationContext";
	
	/** ***** HTTP ServletRequest使用的key *********** */
	public static final String USER_ID = "userId"; 
	public static final String USER_PROFILE_KEY = "UserProfile";
	public static final String VIEWHELP = "viewhelp";

	/** ***** 错误ID*********** */
	private static final int MSG_USER_CONTEXT_NOT_FOUND = 8;

	private static final String[] LOG_MESSAGE_TEXT_EN = {
		"Not in online service hours.",
		"Session Error.",
		"Buttun was clicked more than once.",
		"Page(URL) specified directly withoug logging on or session error.",
		"User is not authorised for this action. Error ID:",
		"Login Error. Error ID:",
		"System Exception.",
		"Tms Application Exception. Error ID:",
		"UserContext not found."
	};	
	
    /**
     * 父类实现
     */
    public final ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
    	
		//参数设置
		HttpSession session 	= null;
		UserContextImpl uc 		= null;

		session = getSession(request);
		
		try{
			//给这个方法中传递一个uc
			//============================================
			// UserContext设置
			//============================================
			uc = getUserContext(session, request);
			uc.setServletParams(request, response);
			
			//具体逻辑执行
			process(mapping,form,request,response,uc);
			
			//UC设置到session
			request.getSession().setAttribute( APPLICATION_USER_CONTEXT_KEY, uc);

			request.setAttribute(USER_PROFILE_KEY, uc.getUserProfile());
			
		} catch (TmsException api) {
			MessageResources messages = getResources(request);
			//错误信息
			StringBuffer sb = new StringBuffer();
			String errorinfo = messages.getMessage(api.getExceptionId(), api.getErrorParams());
			if(!StringUtil.isNullOrBlank(errorinfo)) {
				sb.append(errorinfo);
				sb.append("</br>");
			}
			String errorinfos = getErrorInfoList(api.getActionErrors());
			if(!StringUtil.isNullOrBlank(errorinfos)) {
				sb.append(errorinfos);
			}
			responseValues(response,sb.toString(),TEXT);
		}
		return null;
    }
	/**
	 * 
	 * @param listErrors
	 */
	private String getErrorInfoList(List<ActionMessage> listErrors) {
		StringBuffer sb = new StringBuffer();
		if (listErrors != null && listErrors.size() > 0) {
			for (int i = 0; i < listErrors.size(); i++) {
				ActionMessage messages = (ActionMessage)listErrors.get(i);
				sb.append(messages.toString());
				sb.append("</br>");
			}
		}
		return sb.toString();
	}
    /**
     * 通过response向客户段发送文本信息
     * @param response:请求返回对象
     * @param values:用户生成的具体信息
     * @param type:请求返回文本类型
     * @throws TmsException:出现io错误
     */
    public void responseValues(HttpServletResponse response,String values,String type) throws TmsException{
    	
    	if(XML.equals(type)){
    		response.setContentType(TmsConstants.CONTENTTYPE_TEXTXML);
    	}
    	response.setCharacterEncoding(TmsConstants.ENCODING_UTF8);
 		PrintWriter writer = null;
		try {
			writer = response.getWriter();
			writer.print(values);
		} catch (IOException e) {
			throw new TmsException(TmsException.SYS_IOEXCEPTION,e);
		} finally{
			if(writer!=null){
				writer.close();
			}
		}
    }

    /**
     * 
     * @param session
     * @param request
     * @return
     * @throws Exception
     */
    protected UserContextImpl getUserContext(HttpSession session, HttpServletRequest request) throws Exception {
    	 UserContextImpl uc = (UserContextImpl) session .getAttribute(APPLICATION_USER_CONTEXT_KEY);
         if (null == uc) {
             if (!isNoValidation(request.getRequestURL().toString()) && isCheckLogin(request.getRequestURI())) {
                 logger.error(getLogMessage(MSG_USER_CONTEXT_NOT_FOUND));
                 throw new SessionTimeoutException();
             } else {
                 uc = new UserContextImpl();
             }
         }
         return uc;
    }
     
    
    private boolean isCheckLogin(String url){
    	boolean r = true;
    	if(StringUtils.isNotBlank(url) && (url.contains("dealPlate.tq") 
    	|| url.contains("dealCharge.tq") 
    	|| url.contains("checkCharge.tq")
		|| url.contains("tmsTransBidHistory.tq") 
		|| url.contains("tmsTransAucManagement.tq")
		|| url.contains("carImportExportMonitoringAjaxAction.tq"))){
    		r = false;
    	}
    	return r;
    }
	 
	/**
	 * 
	 * @param msgId
	 * @return
	 */
	private String getLogMessage(int msgId) {
		String[] logMessageText;
		logMessageText = LOG_MESSAGE_TEXT_EN;
		return logMessageText[msgId];
	}
	
	/**
	 * 
	 * @param request
	 * @return
	 */
	protected HttpSession getSession(HttpServletRequest request) {
		return request.getSession(false);
	}
   /**
    * ajaxAction业务具体实现类
    * @param mapping
    * @param form
    * @param request
    * @param response
    * @throws TmsException
    */
    public abstract void process(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response,UserContext uc) throws TmsException;
    
    
    private boolean isNoValidation(String url){
		if(StringUtil.isNullOrBlank(url)) return false;
		return url.contains("carInformationShow") || 
				url.contains("carInformationShow");
	}
}
